#include "LinkList.h"

void TestLinkList() {
    //方式1：
    // LinkList ll = (Node *)malloc(sizeof(Node));
    // ll->next = NULL;

    //方式2：
    Node n;
    n.next = NULL;
    Node* ll = &n;

    for (int i = 0; i < 15; i++)
        AppendElem(ll, i);
    TraveseList(ll, showElem);

    printf("Is empty? %d\n", IsEmpty(ll));
    printf("The length of the linklist: %d\n", GetLength(ll));

    ElemType res;
    GetElem(ll, 2, &res);
    printf("The result is: %d\n", res);

    InsertElem(ll, 0, 9999);
    printf("After inserting elements:\n");
    TraveseList(ll, showElem);

    DeleteElem(ll, 0);
    printf("After deleting elements:\n");
    TraveseList(ll, showElem);

    printf("The length of the linklist: %d\n", GetLength(ll));

    printf("After clearing: \n");
    ClearList(ll);
}

void showElem(ElemType e) {
    printf("The element in LinkList: %d\n", e);
}

//此函数有误
void ClearList(LinkList ll) {
    //简单实现
    Node* p = ll->next;
    ll->next = NULL;
    Node* temp;

    while (p) {
        temp = p->next;
        free(p);
        p = temp;
    }

    /*
    if (ll)
    {
        int length = GetLength(ll);
        for (int i = 0; i < length; i++)
            DeleteElem(ll, 0);
    }
    */
}

BOOL IsEmpty(LinkList ll) {
    if (ll->next)
        return FALSE;
    return TRUE;
}

int GetLength(LinkList ll) {
    int count = 0;
    if (ll) {
        Node* pNode = ll;
        while (pNode->next) {
            pNode = pNode->next;
            count++;
        }
    }
    return count;
}

void GetElem(LinkList ll, int i, ElemType* e) {
    if (ll) {
        if (i < GetLength(ll) && i >= 0) {
            Node* pNode = ll;
            for (int j = 0; j <= i; j++)
                pNode = pNode->next;
            *e = pNode->data;
        }
    }
}

void InsertElem(LinkList ll, int i, ElemType e) {
    if (ll) {
        if (i >= 0 && i < GetLength(ll)) {
            Node* pNode = ll;
            for (int j = 0; j < i; j++)
                pNode = pNode->next;

            Node* temp = pNode->next;

            Node* newElem = (Node*)malloc(sizeof(Node));
            newElem->data = e;
            newElem->next = temp;
            pNode->next = newElem;
        }
        if (i == GetLength(ll)) {
            Node* pNode = ll;
            for (int j = 0; j < i; j++)
                pNode = pNode->next;

            Node* newElem = (Node*)malloc(sizeof(Node));
            newElem->data = e;
            newElem->next = NULL;

            pNode->next = newElem;
        }
    }
}

void AppendElem(LinkList ll, ElemType e) {
    InsertElem(ll, GetLength(ll), e);
}

void DeleteElem(LinkList ll, int i) {
    if (ll) {
        if (i >= 0 && i < GetLength(ll)) {
            Node* pNode = ll;
            for (int j = 0; j < i; j++)
                pNode = pNode->next;

            Node* temp = pNode->next;
            pNode->next = pNode->next->next;
            free(temp);
        }
        if (i == GetLength(ll)) {
            Node* pNode = ll;
            for (int j = 0; j < i; j++)
                pNode = pNode->next;

            Node* temp = pNode->next;
            pNode->next = NULL;

            free(temp);
        }
    }
}

void TraveseList(LinkList ll, void (*visitFunc)(ElemType)) {
    if (ll) {
        Node* pNode = ll;
        while (pNode->next) {
            pNode = pNode->next;
            visitFunc(pNode->data);
        }
    }
}

void DisposeList(LinkList ll) {
    if (ll)
        free(ll);
}